import React, { useEffect, useRef } from "react";
import * as THREE from "three";
import styles from "./index.module.css";

function WaveBackground() {
  const myRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    let scene: THREE.Scene;
    let camera: THREE.PerspectiveCamera;
    let renderer: THREE.WebGLRenderer;
    let particles: THREE.Points;
    let material: THREE.PointsMaterial;

    // 初始化 场景，相机，渲染器
    const init = () => {
      // 初始化场景
      scene = new THREE.Scene();
      // 初始化相机
      camera = new THREE.PerspectiveCamera(
        60, // 相机的视野角度
        window.innerWidth / window.innerHeight, // 渲染比例
        2, //  可以看到的距离
        1000 //  最远可以看到的距离
      );

      //  初始化渲染器
      renderer = new THREE.WebGLRenderer();
      // 设置画布尺寸
      renderer.setSize(window.innerWidth, window.innerHeight);

      // threejs效果 渲染到页面
      myRef.current?.appendChild(renderer.domElement);

      const particleCount: number = 1000;

      // 创建一个存放顶点位置的数组
      const positions: Float32Array = new Float32Array(particleCount * 3);
      for (let i: number = 0; i < particleCount; i++) {
        positions[i * 3] = (Math.random() - 0.5) * 10;
        positions[i * 3 + 1] = (Math.random() - 0.5) * 10;
        positions[i * 3 + 2] = (Math.random() - 0.5) * 10;
      }

      // 创建几何体
      const geometry: THREE.BufferGeometry = new THREE.BufferGeometry();
      // 添加一个存放顶点位置的数组
      geometry.setAttribute(
        "position",
        new THREE.BufferAttribute(positions, 3) //顶点数组 顶点的维度
      );

      // 创建几何体材质
      material = new THREE.PointsMaterial({ size: 0.1, color: "	#FFFFFF" }); // 粒子大小 粒子颜色
      // 将创建的几何体和材质传入，形成一个粒子系统。
      particles = new THREE.Points(geometry, material);
      // 将粒子系统加入场景中展示
      scene.add(particles);

      camera.position.z = 5;
    };

    const animate = () => {
      // 更新粒子系统的旋转角度
      requestAnimationFrame(animate);

      particles.rotation.x += 0.001;
      particles.rotation.y += 0.001;

      // 渲染器将场景渲染到屏幕上
      renderer.render(scene, camera);
    };

    init();
    animate();
  }, []);

  return <div className={styles.WaveBackground} ref={myRef} />;
}

export default WaveBackground;
